﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Evolution
{
    class Population
    {
        private byte widthField;
        private byte heightField;
        private byte[,] populationOld;
        private byte[,] populationNew;

        public Population(byte hField, byte wField)
        {
            this.widthField = wField;
            this.heightField = hField;
            populationOld = new byte[hField + 2, wField + 2];
            populationNew = new byte[hField + 2, wField + 2];

            Random rndNumber = new Random();

            // Main field
            for (int i = 1; i <= hField; i++)
            {
                for (int j = 1; j <= wField; j++)
                {
                    populationOld[i, j] = (byte)rndNumber.Next(2);
                }
            }

            // Bourder of the field
            // It is used for calculation of quantity of neighbors in the general scheme
            for (int i = 0; i <= hField + 1; i++)
            {
                populationOld[i, 0] = 1;
                populationOld[i, wField + 1] = 1;
            }
            for (int j = 0; j <= wField + 1; j++)
            {
                populationOld[0, j] = 1;
                populationOld[hField + 1, j] = 1;
            }

        }

        public void Show()
        {
            for (int i = 1; i <= heightField; i++)
            {
                for (int j = 1; j <= widthField; j++)
                {
                    if (populationOld[i, j] == 0)
                        Console.Write(" ");
                    else
                        Console.Write("*"); 
                }
                Console.WriteLine();
            }
        }
        
        public void Change()
        {
            int countNeighbors;
            int outFieldNeighbors;   // outFieldNeighbors = 0 for cells inside field
                                     // outFieldNeighbors = 3 for cells on the border
                                     // outFieldNeighbors = 5 for cells in corners of the field 
            for (int i = 1; i <= heightField; i++)
            {
                for (int j = 1; j <= widthField; j++)
                {
                    outFieldNeighbors = GetOutNeighbors(i, j);

                    countNeighbors = GetQuantityOfNeighbours(i, j);

                    if (populationOld[i, j] == 1)
                    {
                        if (countNeighbors == 8 - outFieldNeighbors) populationNew[i, j] = 0;
                        else populationNew[i, j] = 1;
                    }
                    else
                    {
                        if (countNeighbors >= 2) populationNew[i, j] = 1;
                        else populationNew[i, j] = 0;
                    }
                    
                }
                
            }
            Array.Copy(populationNew, populationOld, populationNew.Length);
        }
        
        // Return quantity of neighbors outside of field
        private int GetOutNeighbors(int i, int j)
        {
            int outNeighbors = 0;
        
            if (i == 1 || i == heightField || j == 1 || j == widthField)
                outNeighbors = 3;

            if ((i == 1 || i == heightField) && (j == 1 || j == widthField))
                outNeighbors = 5;
            return outNeighbors;
        }

        // Returns total of neighbors
        public int GetQuantityOfNeighbours(int inum, int jnum)
        {
            int count = 0;
            for (int i = inum-1; i <= inum+1; i++)
            {
                for (int j = jnum-1; j <= jnum+1; j++)
                {
                    if (populationOld[i, j] == 1)
                        count++;
                }

            }
            return count - populationOld[inum, jnum];
        }


    }
}
